# -*- coding: utf-8 -*-
class LoanReturnedController < ApplicationController
  before_filter :employee_authorize
  before_filter :sys_before_log
  before_filter :employee_action_hx
  before_filter :privilege_filter,:except=>[:loanReturnedList,:newLoanReturned,:editLoanReturned,:hxListForLoanReturned,:loan_returned_print_header,:loan_returned_print_footer,:loan_returned_print_content]

  def loanReturnedList

  end
  
  #得到所有借货返库订单
  def getAllLoanReturneds
    begin
      conditionsHash = Hash.new
      paramsHash = Hash.new
      paramsHash[:offset] = params[:start].to_i
      paramsHash[:limit] = params[:limit].to_i

      conditionsStr = ''

      if params[:order_number].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'seq_number in (:order_number)'
        else
          conditionsStr = conditionsStr+' AND seq_number in (:order_number)'
        end
        conditionsHash[:order_number] = params[:order_number].split(/,/)
      end

      if params[:auditing_status].to_s != '' && params[:auditing_status] != ' '
        if conditionsStr == ''
          conditionsStr = 'auditing_status like :auditing_status'
        else
          conditionsStr = conditionsStr+' AND auditing_status like :auditing_status'
        end
        conditionsHash[:auditing_status] = '%'+params[:auditing_status].to_s+'%'
      elsif params[:auditing_status] == ' '
        if conditionsStr == ''
          conditionsStr = 'auditing_status = :auditing_status'
        else
          conditionsStr = conditionsStr+' AND auditing_status = :auditing_status'
        end
        conditionsHash[:auditing_status] = ''
      end

      if params[:customer_id].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'customer_id = :customer_id'
        else
          conditionsStr = conditionsStr+' AND customer_id = :customer_id'
        end
        conditionsHash[:customer_id] = params[:customer_id].to_i
      end

      #销售员
      if params[:sales_id].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'sales_id = :sales_id'
        else
          conditionsStr = conditionsStr+' AND sales_id = :sales_id'
        end
        conditionsHash[:sales_id] = params[:sales_id].to_i
      end

      if params[:begin_date].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'action_date >= :begin_date'
        else
          conditionsStr = conditionsStr+' AND action_date >= :begin_date'
        end
        conditionsHash[:begin_date] = params[:begin_date].to_date
      end

      if params[:end_date].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'action_date <= :end_date'
        else
          conditionsStr = conditionsStr+' AND action_date <= :end_date'
        end
        conditionsHash[:end_date] = params[:end_date].to_date
      end

      #显示产品
      if params[:product_id].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'loan_details.product_id = :product_id'
        else
          conditionsStr = conditionsStr+' AND loan_details.product_id = :product_id'
        end
        conditionsHash[:product_id] = params[:product_id].to_i
      end

      #显示产品
      if params[:department_id].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'department_id = :department_id'
        else
          conditionsStr = conditionsStr+' AND department_id = :department_id'
        end
        conditionsHash[:department_id] = params[:department_id].to_i
      end

      count = LoanReturned.countAllLoanReturneds conditionsStr,conditionsHash
      loanReturneds = LoanReturned.findAllLoanReturneds conditionsStr,conditionsHash,paramsHash

      jsonStr="{totalProperty:"+count.to_s+",root:"+loanReturneds.to_json(:include=>[:customer,:loan,:department,:employee,:warehouse])+"}"
      logger.info jsonStr
      render :text=>jsonStr, :layout=>false
    rescue Exception => e
      logger.info e
      DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,e.to_s)
    end
  end

  #显示编辑销售退货订单页面
  def create
    paramsHash = Util.paramsPreprocesseToHash(params[:data])
    
    loanId = paramsHash['loan_id']
    warehouseId = paramsHash['warehouse_id']

    loan =  Loan.find(loanId)
    if loan.deal_with_status == Constants::CANCELED
      info = "已经撤消的索赔订单，不可以再转换为返库订单！"
    elsif loan.store_status == Constants::FINISH_ENTRY
      info = "已经返库完毕的索赔订单，不可以再转换为索赔返库订单！"
    else
      loanReturned = LoanReturned.new
      loanReturned.loan_id = loan.id
      loanReturned.company_id = loan.company_id
      loanReturned.department_id = loan.department_id
      loanReturned.employee_id = loan.employee_id
      loanReturned.action_date = paramsHash['action_date']
      loanReturned.customer_id = loan.customer_id
      loanReturned.warehouse_id = warehouseId
      loanReturned.auditing_status = Constants::PASS_APPLY_ADD
      loanReturned.save!  #先行保存一下，以便生成ID
      #为了在进行结算表操作时提前获取ID，这时要提前存储purchaseOrder

      #向详细表中插入products信息
      productsHashArray = paramsHash["products"]
      productsHashArray.each do |productHash|
        #如果不为空则加入
        if productHash["product_id"] !=""
          #得到采购订单的详细价格，只有取出它的详细记录来。
          loanReturnedDetail = LoanReturnedDetail.new
          loanReturnedDetail.product_id = productHash["product_id"]
          loanReturnedDetail.quantity = productHash["quantity"]
          loanReturnedDetail.description = productHash["description"]
          loanReturned.loan_returned_details << loanReturnedDetail

          #同时生成结算表的内容。
          productCollection = ProductCollection.new
          #copy内容到结算表
          #在进行成功转换后，要同时操作结算表，把此次操作的详细内容，完全拆解开，复制到结算表中。
          productCollection.company_id = loan.company_id
          productCollection.department_id = loan.department_id
          productCollection.employee_id = loan.employee_id
          productCollection.customer_id = loan.customer_id
          productCollection.warehouse_id = warehouseId
          productCollection.product_id = loanReturnedDetail.product_id
          productCollection.quantity = productHash["quantity"] #purchaseOrderDetail.quantity
          productCollection.description =  productHash["description"]
          productCollection.resource_id =  loanReturned.id
          productCollection.resource_type =  LoanReturned.name

          productCollection.action_date = loanReturned.action_date
          productCollection.loan_id =  loanReturned.loan_id
          productCollection.save!
        end
      end

      
      diffs = Loan.diff_loan_returned(loanId)
      if diffs.length ==0
        loan.return_status = Constants::FINISH_RETURN
      end

      #开始事务，确保在流水号正常的情况下，保存入库单时,一但出现问题，则循环执行
      begin
        Sequence.transaction do
          #开始为出库单取得流水号
          sequence = Sequence.find(:first,:conditions=>["company_id = ? AND sub_type = ?",session[:company_id],LoanReturned.name])
          sequence.seq_no = sequence.seq_no + 1
          loanReturned.seq_number = sequence.seq_no
          loanReturned.order_number = sequence.ab + ":" + loanReturned.seq_number.to_s + ":" + Date.today.to_s
          sequence.save!
          loanReturned.save!
          #最后保存采购订单的状态更改。
          loan.save!
        end
      rescue ActiveRecord::StaleObjectError
        #这个异常是说明，你当提交时，有人提前更新了你之前读取的信息，违反乐观锁。要retry
        #这里特别指序号产生表。
        logger.info "somebody useing sn before yours.............................................................."
        DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,"StaleObjectError")
        retry
      rescue ActiveRecord::RecordNotFound
        logger.info "RecordNotFound................................................................................"
        DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,"RecordNotFound")
      rescue Exception => e
        logger.info "logging......................................................................................."
        DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,e.to_s)
        logger.info e
      end
      info = "成功"
    end
    result = "{success:true,info:'#{info}'}"
    render :text=>result, :layout=>false
  end

  def update
    paramsHash = Util.paramsPreprocesseToHash(params[:data])
    
    #productHash = paramsHash["products"][0]
    loanReturned = LoanReturned.find(:first,:conditions=>["id = ? AND company_id = ? AND is_locked <> 1 AND auditing_status not like ? ",paramsHash['id'],session[:company_id],'%撤消%'])
    if loanReturned != nil
      loanReturnedHx = LoanReturnedHx.new
      loanReturnedHx.company_id = loanReturned.company_id
      loanReturnedHx.department_id = loanReturned.department_id
      loanReturnedHx.employee_id = loanReturned.employee_id
      loanReturnedHx.loan_returned_id = loanReturned.id
      loanReturnedHx.loan_id = loanReturned.loan_id
      loanReturnedHx.warehouse_id = loanReturned.warehouse_id
      loanReturnedHx.action_date = loanReturned.action_date
      
      loanReturned.company_id = session[:company_id]
      loanReturned.department_id = session[:department_id]
      loanReturned.employee_id = session[:employee_id]
      loanReturned.warehouse_id = paramsHash['warehouse_id']
      loanReturned.action_date = paramsHash['action_date']
      loanReturned.description = paramsHash['description']

      loanReturned.audit_opinion = ''
      loanReturned.auditor_id = session[:employee_id]

      loanReturned.auditing_status = Constants::PASS_APPLY_EDIT

      #products信息
      productsHashArray = paramsHash["products"]
      #在这里，要作一个增，删，编辑操作，以前台数据为准。
      #首先各取出前台与后台的ID数组
      fgIdArray = Array.new
      productsHashArray.each do |productHash|
        fgIdArray << productHash["id"].to_i
      end

      bgIdArray = Array.new
      loanReturnedDetails = loanReturned.loan_returned_details
      loanReturnedDetails.each do |loanReturnedDetail|
        bgIdArray << loanReturnedDetail.id
        #利用这次循环，生成一次对原记录的备份
        loanReturnedHxDetail = LoanReturnedHxDetail.new
        loanReturnedHxDetail.product_id = loanReturnedDetail.product_id
        loanReturnedHxDetail.quantity = loanReturnedDetail.quantity
        loanReturnedHx.loan_returned_hx_details << loanReturnedHxDetail
      end

      idIntersectionArray = fgIdArray & bgIdArray
      addIdArray = fgIdArray - idIntersectionArray
      delIdArray = bgIdArray - idIntersectionArray
      #得到要删除的产品Id数组

      if !delIdArray.empty?
        loanReturnedDetails = LoanReturnedDetail.find(:all,:conditions=>["id in (?)",delIdArray])
        loanReturnedIdArray = Array.new
        productIdArray = Array.new
        loanReturnedDetails.each do |loanReturnedDetail|
          loanReturnedIdArray << loanReturnedDetail.loan_returned_id
          productIdArray << loanReturnedDetail.product_id
        end
        LoanReturnedDetail.delete(delIdArray)
        #删除汇总表中的相关内容
        ProductCollection.delete_all(["resource_type = 'LoanReturned' AND resource_id = ? AND product_id in (?)",loanReturned.id,productIdArray])
      end

      #在进行从新整理数据之前，先把销售订单的总金额置“0”

      productsHashArray.each do |productHash|
        #只有当用户选择的产品不为空时，才有详细订单。
        if productHash["product_id"] !=""
          #没Id说明是新增加的。
          if productHash["id"] != ""
            loanReturnedDetail = LoanReturnedDetail.find(productHash["id"].to_i)
            loanReturnedDetail.quantity = productHash["quantity"] #对于出入库来说其实只有数量为唯一的考量。
            loanReturnedDetail.description = productHash["description"]
            loanReturnedDetail.save
            #同时把汇总表中的相关记录进行修改
            ProductCollection.update_all("warehouse_id = #{loanReturned.warehouse_id},quantity = #{loanReturnedDetail.quantity}","resource_type = 'LoanReturned' AND resource_id = #{loanReturned.id} AND product_id = #{loanReturnedDetail.product_id} AND is_locked = 0 AND product_id =#{loanReturnedDetail.product_id}")
          end
        end
      end
      loanReturned.save!
      loanReturnedHx.save!
    end

    info="成功"
    result = "{success:true,info:'#{info}'}"
    render :text=>result, :layout=>false
  end

  #得到某一个销售退货订单
  def getLoanReturnedById
    loanReturned = LoanReturned.find(params[:id])
    rootStr = loanReturned.to_json(:include=>[:customer,:loan])
    jsonStr = "{root:["+rootStr+"]}"
    render :text=>jsonStr, :layout=>false
  end

  #根据某个销售退货订单Id得到详细信息
  def getLoanReturnedDetailsById
    loanReturnedDetails = LoanReturnedDetail.find_all_by_loan_returned_id(params[:id])
    jsonStr="{totalProperty:"+loanReturnedDetails.length.to_s+",root:"+loanReturnedDetails.to_json(:include=>{:product=>{:only=>[:id,:name,:is_suit,:spec,:number]}})+"}"
    logger.info jsonStr
    render :text=>jsonStr, :layout=>false
  end

  #在编辑入库单时，根据当前的入库情况判断可返库数量是多少。
  def getDetailsBalanceByIdForEdit
    loanReturnedId = params[:loan_returned_id]
    loanReturned = LoanReturned.find(loanReturnedId)
    loanReturnedDetails = loanReturned.loan_returned_details
    #销售详细
    #balance_quantity为当前最大的可入数量。即修改后的数字不能大于balance_quantity
    loanReturneds = LoanReturned.find(:all,:select=>"rd.id,p.id as product_id,p.name as product_name,p.is_suit,p.unit_price,p.number,p.spec,p.unit,rd.quantity,rd.description,(ld.quantity - ifnull(newrd.quantity,0) + rd.quantity) as balance_quantity",:joins =>"lr
left join loan_returned_details rd on lr.id = rd.loan_returned_id
left join (select loan_returned_id,product_id,sum(quantity) as quantity
from loan_returneds lr left join loan_returned_details rd on lr.id = rd.loan_returned_id
where lr.loan_id = #{loanReturned.loan_id} AND lr.auditing_status != '#{Constants::PASS_APPLY_CANCEL}'
group by product_id) newrd on newrd.product_id = rd.product_id
left join products p on p.id = rd.product_id
left join loan_details ld on ld.loan_id = lr.loan_id AND ld.product_id = rd.product_id
where lr.id =  "+loanReturnedId)

    jsonStr="{totalProperty:"+loanReturneds.length.to_s+",root:"+loanReturneds.to_json()+"}"
    logger.info jsonStr
    render :text=>jsonStr, :layout=>false
  end
  
  #销售退货订单的撤销
  def applyToCancel
    begin
      loanReturned = LoanReturned.find(params[:id])
      sysParam =  SysParam.find_by_company_id(session[:company_id])
      if sysParam.audit_for_loan_returned_cancel == "否"
        loanReturned.auditing_status = Constants::PASS_APPLY_CANCEL
        loanReturned.deal_with_status = Constants::CANCELED
        ProductCollection.delete_all("resource_type = 'LoanReturned' AND resource_id = #{params[:id]}")
        #如果不需要审批，则把汇总表中的数据设置为is_locked = 1
      else
        loanReturned.auditing_status = Constants::AUDIT_APPLY_CANCEL
      end
      loanReturned.auditor_id = session[:employee_id]
      loanReturned.save!
    rescue Exception => e
      info = e.to_s
      logger.info info
      DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,e.to_s)
    end
    info = "成功"
    result = "{success:true,info:'#{info}'}"
    render :text=>result, :layout=>false
  end

  #得到可供返货的借货记录中的产品详细，生成返库订单时用。
  def getProductsOfLoanForReturned
    loanId = params[:loan_id]
    #order_quantity是未转的数量，不代表可以转，因为有时候库存不足
    #总的思路就是显示可前本销售订单可转数，
    loans = Loan.find(:all,:select=>"ld.id,p.id as product_id,p.name as product_name,p.is_suit,p.unit_price,p.number,p.spec,p.unit,ld.description,ld.quantity - ifnull(newrd.quantity,0) as quantity,ld.quantity - ifnull(newrd.quantity,0) as balance_quantity",:joins =>"l
left join loan_details ld on l.id = ld.loan_id
left join (select loan_returned_id,lr.loan_id,product_id,sum(quantity) as quantity
from loan_returneds lr left join loan_returned_details rd on lr.id = rd.loan_returned_id
where lr.loan_id = "+loanId+" AND lr.auditing_status != '#{Constants::PASS_APPLY_CANCEL}'
group by product_id) newrd on newrd.product_id = ld.product_id
left join products p on p.id = ld.product_id
where (ld.quantity - ifnull(newrd.quantity,0)) > 0 AND l.id =  "+loanId)

    jsonStr="{totalProperty:"+loans.length.to_s+",root:"+loans.to_json()+"}"
    logger.info jsonStr
    render :text=>jsonStr, :layout=>false
  end

  #得到变更历史的摘要
  def getHxesById
    loanReturnedHxes = LoanReturnedHx.find_all_by_loan_returned_id(params[:id],:include=>[:department,:employee,:warehouse])
    jsonStr="{totalProperty:"+loanReturnedHxes.length.to_s+",root:"+loanReturnedHxes.to_json(:include=>[:department,:employee,:warehouse])+"}"
    logger.info jsonStr
    render :text=>jsonStr, :layout=>false
  end

  #根据变更Id得到详细信息
  def getHxDetailsByHxId
    loanReturnedHxDetails = LoanReturnedHxDetail.find_all_by_loan_returned_hx_id(params[:id],:include=>[:product])
    jsonStr="{totalProperty:"+loanReturnedHxDetails.length.to_s+",root:"+loanReturnedHxDetails.to_json(:include=>{:product=>{:only=>[:id,:name,:is_suit,:spec]}})+"}"
    logger.info jsonStr
    render :text=>jsonStr, :layout=>false
  end

  #生成打印销售凭证的头部
  def loan_returned_print_header
    @loanReturned = LoanReturned.find(params[:id],:include=>[:warehouse,:loan,:customer])
    @loan = @loanReturned.loan
  end

  #生成打印销售凭证的内容
  def loan_returned_print_content
    @loanReturned = LoanReturned.find(params[:id],:include=>[:loan_returned_details,:loan,:customer,:warehouse])
    @loanReturnedDetails = @loanReturned.loan_returned_details
    @totalQuantity = @loanReturnedDetails.sum(:quantity)
    logger.info @totalQuantity
  end

  def loan_returned_print_footer
    @loanReturned = LoanReturned.find(params[:id],:include=>[:loan_returned_details,:loan,:customer,:warehouse])
  end
end
